package com.study.system.user.config;

import com.alibaba.fastjson.JSON;
import com.study.system.user.handler.LoginSuccessHandler;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

/**
 * Security配置
 */
@EnableWebSecurity
@Configuration
public class SecurityConfig {

    /**
     * 提供密码编码器
     * @return
     */
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http,
                                                       BCryptPasswordEncoder encoder,
                                                       UserDetailsService userDetailsService) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(userDetailsService)
                .passwordEncoder(encoder)
                .and()
                .build();
    }

    @Resource
    private LoginSuccessHandler loginSuccessHandler;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests( a -> {
                    a.requestMatchers("/login","/logout").permitAll() //放行部分url不做验证
                            .anyRequest().authenticated();                //其它请求url都要验证
                })
                .formLogin()       //登录相关配置
                .loginProcessingUrl("/login")  //登录url
                .successHandler(loginSuccessHandler) //成功处理器
                .failureHandler(((request, response, exception) -> {
                    response.addHeader("Content-Type","application/json;charset=UTF-8");
                    response.getWriter().write(JSON.toJSONString(ResponseEntity.ok("登录失败")));
                }))
                .and()
                .exceptionHandling()  //请求未经验证的异常
                .authenticationEntryPoint(((request, response, authException) -> {
                    response.addHeader("Content-Type","application/json;charset=UTF-8");
                    response.getWriter().write(JSON.toJSONString(ResponseEntity.ok("没有登录")));
                }))
                .and()
                .logout()                     //注销操作配置
                .logoutUrl("/logout")
                .logoutSuccessHandler(((request, response, authentication) -> {
                    response.addHeader("Content-Type","application/json;charset=UTF-8");
                    response.getWriter().write(JSON.toJSONString(ResponseEntity.ok("注销成功")));
                }))
                .clearAuthentication(true)    //清理验证信息
                .and()
                .csrf()
                .disable()                     //禁用csrf
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)         //session策略为无状态
                .and()
                .addFilterAfter(new TokenValidateFilter(), BasicAuthenticationFilter.class);
        return http.build();
    }
}
